unit lsComponent;

interface

uses
  ExtCtrls, XMLIntf, Contnrs, Classes, Controls;

type
  TlsEvent = procedure(AMsg: String) of Object;

  TlsComponent = class
  private
    FPathOfTrain: string;
    procedure SetPathOfTrain(const Value: string);
    function GetResponseTime: Cardinal;
  protected
    FParent: TWinControl;
    FTimers: TObjectList;
    FResponseTime: Cardinal;
    FEvents: TStringList;
    procedure innerDoAction(AAction: String); virtual;
    procedure ResponseTimer(Sendor: TObject);
    procedure DoEventByType(const AType: string);
  public
    lsConfig: IXMLNode;   //<component> ... </component>
    OnlsEvent: TlsEvent;
    constructor Create(AParent: TWinControl;AlsConfig: IXMLNode);virtual;
    destructor  Destroy;override;
    procedure Recv(AMsg:String);virtual;
    procedure DoAction(AAction: String;ADelay: Integer);virtual;
    procedure Refresh;virtual;
    procedure SetProperty(ANode: IXMLNode);virtual; //<left>100</left>
    procedure FireEvent(AMsg: String);virtual;
    property PathOfTrain: string read FPathOfTrain write SetPathOfTrain;
    property ResponseTime: Cardinal read GetResponseTime;
  end;

implementation

uses
  SysUtils, CommonUtils;

constructor TlsComponent.Create(AParent: TWinControl;AlsConfig: IXMLNode);
var
  Node1: IXMLNode;
  I: Integer;
begin
  FTimers := TObjectList.Create;
  FParent:=AParent;
  lsConfig:=AlsConfig;

  FEvents := TStringList.Create;
  Node1:=lsConfig.ChildNodes.FindNode('event');
  for I := 0 to Node1.ChildNodes.Count-1 do
  begin
    FEvents.Add(Node1.ChildNodes.Get(i).NodeName + '=' +
      Node1.ChildNodes.Get(i).NodeValue)
  end;
end;

destructor TlsComponent.Destroy;
begin
  FTimers.Free;
  inherited;
end;

procedure TlsComponent.DoAction(AAction: String; ADelay: Integer);
var
  oTimer: TTimer;
begin
  if ADelay = 0 then
  begin
    innerDoAction(AAction);
    DoEventByType(AAction);
  end
  else begin
    oTimer := TTimer.Create(nil);
    FTimers.Add(oTimer);
    oTimer.Name := AAction;
    oTimer.Interval := ADelay;
    oTimer.OnTimer := ResponseTimer;
    oTimer.Enabled := True;
  end;
end;

procedure TlsComponent.DoEventByType(const AType: string);
begin
  if FEvents.Values[AType] <> '' then
    FireEvent(FEvents.Values[AType]);
end;


procedure TlsComponent.FireEvent(AMsg: String);
begin
  if Assigned(OnlsEvent) then
    OnlsEvent(AMsg);
end;

function TlsComponent.GetResponseTime: Cardinal;
begin
  Result := FResponseTime;
end;

procedure TlsComponent.innerDoAction(AAction: String);
begin
  // donothing
end;

procedure TlsComponent.Recv(AMsg: String);
var
  i: Integer;
  Node1,Node2: IXMLNode;
  Trigger1: String;
  Delay1: Integer;
begin
  if SameText(AMsg, 'unload') then
    ClearControl(FParent);
    
  Node1:=lsConfig.ChildNodes.FindNode('action');
  for i := 0 to Node1.ChildNodes.Count-1 do
  begin
    Node2:=Node1.ChildNodes.Get(i);
    Trigger1:=Node2.ChildNodes.FindNode('trigger').NodeValue;
    Delay1:=Node2.ChildNodes.FindNode('delay').NodeValue;
    if Trigger1=AMsg then begin
      DoAction(Node2.NodeName,Delay1);
    end;
  end;
end;

procedure TlsComponent.Refresh;
var
  PropertyNode1,ActionNode1,EventNode1: IXMLNode;
begin
  PropertyNode1:=lsConfig.ChildNodes.FindNode('property');
  ActionNode1:=lsConfig.ChildNodes.FindNode('action');
  EventNode1:=lsConfig.ChildNodes.FindNode('event');
  SetProperty(PropertyNode1);
end;

procedure TlsComponent.ResponseTimer(Sendor: TObject);
begin
  innerDoAction(TTimer(Sendor).Name);
  DoEventByType(TTimer(Sendor).Name);
  TTimer(Sendor).OnTimer := nil;
  TTimer(Sendor).Enabled := False;
  FTimers.Remove(Sendor);
end;

procedure TlsComponent.SetPathOfTrain(const Value: string);
begin
  FPathOfTrain := Value;
end;

procedure TlsComponent.SetProperty(ANode: IXMLNode);
begin
  // donothing
end;

end.
